#include <iostream>
#include <fstream>
#include <string>
#include <list>
#include <vector>

#include <memory>

#include <suggest/suggest.h>
#include <ncurses.h>

using namespace suggest;

int main(int argc, char** argv) {
	// read a simple file with keyboard description
	// file format:
	// keyboard_width keyboard_height
	// key_width key_height
	// num_keys
	// char x y width height
	// char x y width height
	// ...
	std::ifstream keylist("keylist.txt");

	vec2f keyboard_size;
	vec2f common_key_size;
	keylist >> keyboard_size.x >> keyboard_size.y;
	keylist >> common_key_size.x >> common_key_size.y;

	int num_keys;
	keylist >> num_keys;

	if (!keylist.good())
		return -1;

	std::vector<Key> keys(num_keys);
	for (int i=0; i<num_keys; ++i) {
		std::string codestr;
		keylist >> codestr
				>> keys[i].rect.pos.x >> keys[i].rect.pos.y
				>> keys[i].rect.size.x >> keys[i].rect.size.y;

		if (!keylist.good())
			return -1;

		if (codestr == std::string("SPC")) {
			keys[i].code = ' ';
		} else {
			keys[i].code = codestr.c_str()[0];
		}
	}

	// create suggestion engine with key list
	std::unique_ptr<SuggestEngine> engine(NewSuggestEngine(
		keyboard_size, common_key_size, keys, SuggestParameters("en_US")));
	if(!engine->LoadDictionary("en_US"))
		return -1;

	// do some test touches and receive suggestions
	std::unique_ptr<SuggestSession> session(engine->NewSession());

	initscr();
	std::vector<Touch> touches;
	std::string display = "$ ";
	while (true) {
		char c = getch();
		if (c == ' ') {
			display.append(1, c);
			touches.clear();
		} else if (c == '\n') {
			Suggestion suggestion = *session->GetSuggestions(touches).begin();
			display = display.substr(0, display.rfind(' ')+1);
			display += suggestion.word + " ";
			touches.clear();
		} else {
			display.append(1, c);
			touches.push_back(Touch(c, *engine));
		}
		move(0, 0);
		printw(display.c_str());
		move(1, 0);
		for (const Suggestion &suggestion: session->GetSuggestions(touches)) {
			printw("%s - %d\n", suggestion.word.c_str(), suggestion.frequency);
		}
		refresh();
	}
	endwin();
	return 0;
}